import { Breadcrumb, Icon, Layout, Menu, Spin } from "@arco-design/web-react";
import styles from "./style/layout.module.less";
import Navbar from "./components/Navbar";
import { Route, Routes, useLocation, useNavigate } from "react-router-dom";
import { IconBook, IconDashboard, IconExperiment, IconFindReplace, IconList, IconMenuFold, IconMenuUnfold, IconSettings, IconUser } from "@arco-design/web-react/icon";
import React, { lazy, Suspense, useEffect, useMemo, useRef, useState } from "react";
import useRoute, { IRoute } from "./routes";
import qs from 'query-string';
import NProgress from 'nprogress'
const MenuItem = Menu.Item;
const { SubMenu } = Menu;
const Sider = Layout.Sider;
const Content = Layout.Content;

// 通过key获取icon
function getIconFromKey(key: any) {
  switch (key) {
    case "advertising":
      return <IconUser className={styles.icon} />;
    case "attribution":
      return <IconBook className={styles.icon} />;
    case "echarts":
      return <IconFindReplace className={styles.icon}/>;
    case "power":
      return <IconList className={styles.icon}/>;
    case "forcast":
      return <IconDashboard className={styles.icon}/>;
    case "system":
      return <IconSettings className={styles.icon}/>;
    case "pollution":
      return <IconExperiment className={styles.icon}/>;
    default:
      return <div className={styles["icon-empty"]} />;
  }
}
// 获取扁平化的路由
// function getFlattenRoutes(routes: any) {
//   const res: any = [];
//   function travel(_routes: any) {
//     _routes?.forEach((route: any) => {
//       if (route.key && route.element) {
//         const Element = route.element;
//         route.ellement = (
//           <Suspense
//             fallback={
//               <div className="flex items-center justify-center w-full min-h-[60vh]">
//                 <Spin />
//               </div>
//             }
//           >
//             <Element />
//           </Suspense>
//         );
//         res.push(route);
//       }
//       if (Array.isArray(route.children) && route.children.length) {
//         travel(route.children);
//       }
//     });
//   }
//   travel(routes);
//   return res;
// }
export function LazyElement(props: any) {
  const { importFunc } = props;
  const LazyComponent = lazy(importFunc);
  console.log('111')
  return (
    <Suspense
      fallback={
        <div className="flex items-center justify-center w-full min-h-[60vh]">
          <Spin />
        </div>
      }
    >
      <LazyComponent />
    </Suspense>
  );
}
function getFlattenRoutes(routes) {
  const res = [];
  function travel(_routes) {
    _routes?.forEach((route) => {
      if (route.key && route.element) {
        try {
          const isElementFunc =
            route.element && typeof route.element == 'function';
          const Element = isElementFunc ? (
            <LazyElement importFunc={route.element} />
          ) : (
            route.element
          );
          route.element = Element;
          res.push(route);
        } catch (e) {
          console.error(e);
        }
      }
      if (Array.isArray(route.children) && route.children.length) {
        travel(route.children);
      }
    });
  }
  travel(routes);
  return res;
}
export default function PageLayout() {
  const navigate = useNavigate(); // 获取路由跳转函数
  const [routes, defaultRoute] = useRoute(); // 获取路由
  const flattenRoutes = useMemo(() => getFlattenRoutes(routes), [routes]); // 获取扁平化的路由
  const routeMap = useRef<Map<string, React.ReactNode[]>>(new Map()); 
  const menuMap = useRef< 
    Map<string, { menuItem?: boolean; subMenu?: boolean }>
  >(new Map()); // 获取菜单项和子菜单项
  const { pathname } = useLocation(); // 获取当前路由
  const currentComponent = qs.parseUrl(pathname).url.slice(1); // 获取当前路由对应的组件
  const paths = (currentComponent || defaultRoute).split('/'); // 获取当前路由的路径数组
  const defaultSelectedKeys = [currentComponent || defaultRoute]; // 获取默认选中的菜单项
  const defaultOpenKeys = paths.slice(0,paths.length - 1); // 获取默认展开的菜单项
  const [breadcrumb, setBreadCrumb] = useState([]); // 获取面包屑
  const [collapsed, setCollapsed] = useState<boolean>(false); // 获取菜单栏是否折叠
  const [selectedKeys, setSelectedKeys] = useState<string[]>(defaultSelectedKeys); // 获取当前选中的菜单项
  const navbarHeight = 60;
  const menuWidth = collapsed ? 48 : 220; // 菜单栏宽度
  const padingLeft = {paddingLeft:menuWidth}
  const paddingContent = {...padingLeft}
  const [openKeys, setOpenKeys] = useState<string[]>(defaultOpenKeys); // 获取当前展开的菜单项
  // 更新菜单状态
  function updateMenuStatus() {
    const pathKeys = pathname.split('/');
    const newSelectedKeys: string[] = [];
    const newOpenKeys: string[] = [...openKeys];
    while (pathKeys.length > 0) {
      const currentRouteKey = pathKeys.join('/');
      const menuKey = currentRouteKey.replace(/^\//, '');
      const menuType = menuMap.current.get(menuKey);
      if (menuType && menuType.menuItem) {
        newSelectedKeys.push(menuKey);
      }
      if (menuType && menuType.subMenu && !openKeys.includes(menuKey)) {
        newOpenKeys.push(menuKey);
      }
      pathKeys.pop();
    }
    setSelectedKeys(newSelectedKeys);
    setOpenKeys(newOpenKeys);
  }

  // 带有路由参数的路由 回显面包屑
  const setDefaultBreadCrumb = () => {
    const res = flattenRoutes.filter((item) => {
      // const reg = /\/:[a-zA-Z0-9_]+(\?)?/gi;
      // if (item.key.indexOf(':') !== -1) {
      //   const filteredPath = item.key.replaceAll(reg, '');
      //   return dynamicParamsHandle(
      //     pathname.slice(1).split('/'),
      //     filteredPath.split('/'),
      //   );
      // } else {
        return pathname.includes(item.key);
      // }
    });
    // console.log(res)
    // if (res.length > 0) {
    //   const startPath = res[0].name.split('.').slice(0, 2).join('.') ?? '';
    //   const routeConfig = res.map((item) => item?.name) ?? [];
    //   routeConfig.unshift(startPath);
    //   // setDefaultMenuSelect(routeConfig[routeConfig.length - 1]);
    //   // 面包屑展示基于表单形式的 根据表单类型(创建、编辑、查看) 拼接面包屑
    //   let routeBreadCrumb = routeConfig || [];
    //   if (urlParams.type) {
    //     routeBreadCrumb = routeConfig.slice(0, -1);
    //     routeBreadCrumb.push(urlParams.type);
    //   }
    //   setBreadCrumb(routeBreadCrumb);
    // }
  };

  useEffect(() => {
    updateMenuStatus();
    if (routeMap.current.size > 0) {
      const routeConfig = routeMap.current.get(pathname);
      if (routeConfig) {
        setBreadCrumb(routeConfig || []);
      } else {
        setDefaultBreadCrumb();
      }
    } else {
      setDefaultBreadCrumb();
    }
  }, [pathname]);

  // 渲染路由
  function renderRoutes() {
    routeMap.current.clear();
    return function travel(_routes: IRoute[], level: number, parentNode = []) {
      return _routes?.map((route: IRoute) => {
        const { breadcrumb = true, ignore } = route;
        const iconDom = getIconFromKey(route.key);
        const titleDom = (
          <>
            {iconDom} {route.text}
          </>
        );
        routeMap.current.set(
          `/${route.key}`,
          breadcrumb ? [...parentNode, route.name] : []
        );
        const visibleChildren = (route.children || []).filter((child) => {
          const { ignore, breadcrumb = true } = child;
          if (ignore || route.ignore) {
            routeMap.current.set(
              `/${child.key}`,
              breadcrumb ? [...parentNode, route.name, child.name] : []
            );
          }
          return !ignore;
        });
        if (ignore) {
          return "";
        }
        if (visibleChildren.length) {
          menuMap.current.set(route.key, { subMenu: true });
          return (
            <SubMenu key={route.key} title={titleDom}>
              {travel(visibleChildren, level + 1, [...parentNode, route.name])}
            </SubMenu>
          );
        }
        menuMap.current.set(route.key, { menuItem: true });
        return <MenuItem key={route.key}>{titleDom}</MenuItem>;
      });
    };
  }
  function MapBreadCrumb(arr, target){
    for(let item of arr){
      if(item.name===target) return item.text
      if(item.children && Array.isArray(item.children)){
        const result = MapBreadCrumb(item.children,target)
        if(result) return result
      }
    }
    return ''
  }
  function onClickMenuItem(key: any) {
    
    const currentRoute = flattenRoutes.find((r: any) => r.key === key);
    // debugger
    // console.log(currentRoute.componentPath,key)
    NProgress.start();
    navigate(`/${key}`);
    // navigate(`/${currentRoute.componentPath}`);
    NProgress.done();
  }

// console.log(flattenRoutes)
  return (
    <div>
      <Layout className={styles.layout}>
        <div className={styles["layout-navbar"]}>
          <Navbar />
        </div>
        <Layout>
          <Sider 
          width={menuWidth}className={styles["layout-sider"]}>
            <div className={styles["menu-wrapper"]}>
              <Menu
              accordion
              collapse={collapsed} 
              onClickMenuItem={onClickMenuItem}
              selectedKeys={selectedKeys}
              openKeys={openKeys}
              onClickSubMenu={(_,openKeys)=>{setOpenKeys(openKeys)}}
              >
                {renderRoutes()(routes, 1)}
              </Menu>
            </div>
            <div className={styles["collapse-btn"]} onClick={()=>setCollapsed(!collapsed)}>
              {collapsed ? <IconMenuUnfold /> : <IconMenuFold />}
            </div>
          </Sider>
          <Layout className={styles["layout-content"]} style={paddingContent}>
            <div className={styles["layout-content-wrapper"]}>
              <div className={styles["layout-breadcrumb"]}>
                {!!breadcrumb.length && (
                  <div className={styles['layout-breadcrumb']}>
                    <Breadcrumb>
                      {breadcrumb.map((item,index)=>(
                        <Breadcrumb.Item key={index}>{MapBreadCrumb(routes,item)}</Breadcrumb.Item>
                      ))}
                    </Breadcrumb>
                  </div>
                )}
              </div>
              <Content>
                <Suspense
                  fallback={
                    <div className="flex items-center justify-center w-full min-h-[60vh]">
                      <Spin />
                    </div>
                  }
                >
                  <Routes>
                    {flattenRoutes.map((route: any, index: any) => (
                      <Route
                        key={index}
                        path={route.key}
                        element={route.element}
                      />
                    ))}
                  </Routes>
                </Suspense>
              </Content>
            </div>
          </Layout>
        </Layout>
      </Layout>
    </div>
  );
}
